package com.wujunshen.swagger.web.controller;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

import com.wujunshen.swagger.annotation.ApiVersion;
import com.wujunshen.swagger.entity.Book;
import com.wujunshen.swagger.exception.ResponseStatus;
import com.wujunshen.swagger.service.BookService;
import com.wujunshen.swagger.web.vo.response.BaseResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author frank woo(吴峻申) <br>
 * email:<a href="mailto:frank_wjs@hotmail.com">frank_wjs@hotmail.com</a> <br>
 * @date 2020/2/7 5:33 下午 <br>
 */
@RestController
@Api(value = "/")
@Slf4j
public class BookController extends BaseController {
    @Resource
    private BookService bookService;
    
    /**
     * @param book 传入的book对象实例
     * @return 成功或失败信息，json格式封装
     */
    @PostMapping(
            value = "/api/books",
            consumes = {APPLICATION_JSON_VALUE},
            produces = {APPLICATION_JSON_VALUE})
    @ApiOperation(
            value = "添加某本书籍",
            httpMethod = "POST",
            notes = "添加成功返回bookId",
            response = BaseResponse.class)
    @ApiVersion(version = "v1.0")
    public BaseResponse<Object> saveBook(
            @Valid @ApiParam(value = "添加的某本书籍信息", required = true) @RequestBody Book book,
            BindingResult bindingResult) {
        BaseResponse<Object> baseResponse = getValidatedResult(bindingResult);
        if (baseResponse != null) {
            return baseResponse;
        }
        
        baseResponse = new BaseResponse<>();
        bookService.saveBook(book);
        if (book.getBookId() != 0) {
            baseResponse.setCode(ResponseStatus.OK.getCode());
            baseResponse.setMessage(ResponseStatus.OK.getMessage());
            baseResponse.setData(book.getBookId());
        } else {
            baseResponse.setCode(ResponseStatus.DATA_CREATE_ERROR.getCode());
            baseResponse.setMessage(ResponseStatus.DATA_CREATE_ERROR.getMessage());
        }
        
        return baseResponse;
    }
    
    /**
     * @return 成功或失败信息，json格式封装
     */
    @GetMapping(value = "/api/books", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(
            value = "查询所有书籍",
            httpMethod = "GET",
            notes = "查询所有书籍",
            response = BaseResponse.class)
    @ApiVersion(version = "v1.1")
    public BaseResponse<Object> getBooks() {
        BaseResponse<Object> baseResponse = new BaseResponse<>();
        List<Book> books = bookService.getBooks();
        if ((books != null) && (!books.isEmpty())) {
            baseResponse.setData(books);
            baseResponse.setCode(ResponseStatus.OK.getCode());
            baseResponse.setMessage(ResponseStatus.OK.getMessage());
        } else {
            baseResponse.setCode(ResponseStatus.DATA_RE_QUERY_ERROR.getCode());
            baseResponse.setData("Query books failed");
            baseResponse.setMessage(ResponseStatus.DATA_RE_QUERY_ERROR.getMessage());
        }
        
        return baseResponse;
    }
    
    /**
     * @param bookId 传入的bookId
     * @return 成功或失败信息，json格式封装
     */
    @GetMapping(value = "/api/books/{bookId:[0-9]*}")
    @ApiOperation(
            value = "查询某本书籍",
            httpMethod = "GET",
            notes = "根据bookId，查询到某本书籍",
            response = BaseResponse.class)
    @ApiVersion(version = "v1.2")
    public BaseResponse<Object> getBook(
            @ApiParam(value = "书籍ID", required = true) @PathVariable("bookId") Integer bookId) {
        log.info("请求参数bookId值：{}", bookId);
        Book book = bookService.getBook(bookId);
        BaseResponse<Object> baseResponse = new BaseResponse<>();
        if (book != null) {
            log.info("查询到书籍ID为{}的书籍", bookId);
            baseResponse.setData(book);
            baseResponse.setCode(ResponseStatus.OK.getCode());
            baseResponse.setMessage(ResponseStatus.OK.getMessage());
        } else {
            log.info("没有查询到书籍ID为{}的书籍", bookId);
            baseResponse.setCode(ResponseStatus.DATA_RE_QUERY_ERROR.getCode());
            baseResponse.setData("Query book failed id=" + bookId);
            baseResponse.setMessage(ResponseStatus.DATA_RE_QUERY_ERROR.getMessage());
        }
        
        return baseResponse;
    }
    
    @PutMapping(value = "/api/books/{bookId:[0-9]*}")
    @ApiOperation(
            value = "更新某本书籍",
            httpMethod = "PUT",
            notes = "更新的某本书籍信息",
            response = BaseResponse.class)
    @ApiVersion(version = "v1.0")
    public BaseResponse<Object> updateBook(
            @NotNull @ApiParam(value = "要更新的某本书籍ID", required = true) @PathVariable("bookId")
                    Integer bookId,
            @Valid @ApiParam(value = "要更新的某本书籍信息", required = true) @RequestBody Book book,
            BindingResult bindingResult) {
        log.info("请求参数bookId值：{}", bookId);
        BaseResponse<Object> baseResponse = getValidatedResult(bindingResult);
        if (baseResponse != null) {
            return baseResponse;
        }
        
        baseResponse = new BaseResponse<>();
        if (bookId == null || book == null) {
            baseResponse.setCode(ResponseStatus.DATA_INPUT_ERROR.getCode());
            baseResponse.setMessage(ResponseStatus.DATA_INPUT_ERROR.getMessage());
            return baseResponse;
        }
        
        if (bookService.getBook(bookId) == null) {
            baseResponse.setCode(ResponseStatus.DATA_RE_QUERY_ERROR.getCode());
            baseResponse.setData("book id=" + bookId + " not existed");
            baseResponse.setMessage(ResponseStatus.DATA_RE_QUERY_ERROR.getMessage());
            return baseResponse;
        }
        
        if (bookService.updateBook(bookId, book) != 1) {
            baseResponse.setData("Update book failed id=" + book.getBookId());
            baseResponse.setCode(ResponseStatus.DATA_UPDATED_ERROR.getCode());
            baseResponse.setMessage(ResponseStatus.DATA_UPDATED_ERROR.getMessage());
        } else {
            baseResponse.setData("Update book id=" + bookId);
            baseResponse.setCode(ResponseStatus.OK.getCode());
            baseResponse.setMessage(ResponseStatus.OK.getMessage());
        }
        
        return baseResponse;
    }
    
    @DeleteMapping(value = "/api/books/{bookId:[0-9]*}")
    @ApiOperation(
            value = "删除某本书籍信息",
            httpMethod = "DELETE",
            notes = "删除某本书籍信息",
            response = BaseResponse.class)
    @ApiVersion(version = {"v1.0", "v1.1", "v1.2"})
    public BaseResponse<Object> deleteBook(
            @ApiParam(value = "要删除的某本书籍ID", required = true) @PathVariable("bookId") Integer bookId) {
        BaseResponse<Object> baseResponse = new BaseResponse<>();
        if (bookService.deleteBook(bookId) != 1) {
            baseResponse.setData("Deleted book failed id=" + bookId);
            baseResponse.setCode(ResponseStatus.DATA_DELETED_ERROR.getCode());
            baseResponse.setMessage(ResponseStatus.DATA_DELETED_ERROR.getMessage());
        } else {
            baseResponse.setData("Deleted book id=" + bookId);
            baseResponse.setCode(ResponseStatus.OK.getCode());
            baseResponse.setMessage(ResponseStatus.OK.getMessage());
        }
        return baseResponse;
    }
}
